package cn.iocoder.yudao.module.book.controller.app.plan;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.book.controller.app.plan.vo.AppPlanCreateReqVO;
import cn.iocoder.yudao.module.book.controller.app.plan.vo.AppPlanWithItemsRespVO;
import cn.iocoder.yudao.module.book.controller.app.plan.vo.AppPlanUpdateReqVO;
import cn.iocoder.yudao.module.book.controller.app.plan.vo.AppPlanCollectionItemRespVO;
import cn.iocoder.yudao.module.book.controller.app.booksShell.vo.AppCollectionsRespVO;
import cn.iocoder.yudao.module.book.dal.dataobject.plans.PlanItemDO;
import cn.iocoder.yudao.module.book.dal.dataobject.plans.PlansDO;
import cn.iocoder.yudao.module.book.dal.mysql.plans.PlanItemMapper;
import cn.iocoder.yudao.module.book.dal.mysql.plans.PlansMapper;
import cn.iocoder.yudao.module.book.service.users.userDTOService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

@Tag(name = "用户 APP - 阅读计划")
@RestController
@RequestMapping("/api/user/plan")
@Validated
public class AppPlanController {

    @Resource
    private PlansMapper plansMapper;

    @Resource
    private PlanItemMapper planItemMapper;

    @Resource
    private userDTOService userService;

    @Resource
    private cn.iocoder.yudao.module.book.service.collections.CollectionsService collectionsService;

    @PostMapping("/create")
    @Operation(summary = "创建阅读计划")
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Integer> createPlan(@Valid @RequestBody AppPlanCreateReqVO req) {
        Long uid = userService.getCurrentUserId();
        PlansDO plan = PlansDO.builder()
                .userId(uid == null ? null : uid.intValue())
                .bookId(null)
                .collectionId(null)
                .planName(req.getTitle())
                .planType(req.getType())
                .dailyCount(req.getNewPerDay())
                .reviewSchedule(String.valueOf(req.getReviewTimes()))
                .build();
        plansMapper.insert(plan);
        Integer planId = plan.getPlanId();
        if (req.getCollectionIds() != null) {
            for (Integer cid : req.getCollectionIds()) {
                planItemMapper.insert(PlanItemDO.builder().planId(planId).collectionId(cid).build());
            }
        }
        return success(planId);
    }

    @GetMapping("/list")
    @Operation(summary = "我的阅读计划列表")
    public CommonResult<List<AppPlanWithItemsRespVO>> myPlans() {
        Long uid = userService.getCurrentUserId();
        List<PlansDO> list = plansMapper.selectList(PlansDO::getUserId, uid == null ? null : uid.intValue());
        List<AppPlanWithItemsRespVO> resp = list.stream().map(p -> {
            List<PlanItemDO> items = planItemMapper.selectList(PlanItemDO::getPlanId, p.getPlanId());
            List<AppPlanCollectionItemRespVO> cols = items.stream().map(it -> {
                AppCollectionsRespVO col = null;
                try { col = collectionsService.selectByLang(it.getCollectionId(), 1); } catch (Exception ignore) {}
                String title = col != null ? col.getTitle() : null;
                String image = col != null ? col.getImage() : null;
                return new AppPlanCollectionItemRespVO(it.getCollectionId(), title, image);
            }).collect(Collectors.toList());
            String cover = cols != null && !cols.isEmpty() ? cols.get(0).getImage() : null;
            return new AppPlanWithItemsRespVO(p.getPlanId(), p.getPlanName(), cover, "", p.getDailyCount(), cols);
        }).collect(Collectors.toList());
        return success(resp);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除阅读计划")
    public CommonResult<Boolean> delete(@RequestParam("id") Integer id){
        planItemMapper.delete(PlanItemDO::getPlanId, id);
        plansMapper.deleteById(id);
        return success(true);
    }

    @GetMapping("/get")
    @Operation(summary = "获取单个阅读计划详情")
    public CommonResult<AppPlanWithItemsRespVO> get(@RequestParam("id") Integer id) {
        PlansDO p = plansMapper.selectById(id);
        if (p == null) {
            return success(null);
        }
        List<PlanItemDO> items = planItemMapper.selectList(PlanItemDO::getPlanId, id);
        List<AppPlanCollectionItemRespVO> cols = items.stream().map(it -> {
            AppCollectionsRespVO col = null;
            try { col = collectionsService.selectByLang(it.getCollectionId(), 1); } catch (Exception ignore) {}
            String title = col != null ? col.getTitle() : null;
            String image = col != null ? col.getImage() : null;
            return new AppPlanCollectionItemRespVO(it.getCollectionId(), title, image);
        }).collect(Collectors.toList());
        String cover = cols != null && !cols.isEmpty() ? cols.get(0).getImage() : null;
        AppPlanWithItemsRespVO resp = new AppPlanWithItemsRespVO(p.getPlanId(), p.getPlanName(), cover, "", p.getDailyCount(), cols);
        return success(resp);
    }

    @PutMapping("/update")
    @Operation(summary = "更新阅读计划")
    @Transactional(rollbackFor = Exception.class)
    public CommonResult<Boolean> update(@Valid @RequestBody AppPlanUpdateReqVO req) {
        PlansDO exist = plansMapper.selectById(req.getId());
        if (exist == null) {
            return success(false);
        }
        PlansDO update = PlansDO.builder()
                .planId(req.getId())
                .planName(req.getTitle() != null ? req.getTitle() : exist.getPlanName())
                .planType(req.getType() != null ? req.getType() : exist.getPlanType())
                .dailyCount(req.getNewPerDay() != null ? req.getNewPerDay() : exist.getDailyCount())
                .reviewSchedule(req.getReviewTimes() != null ? String.valueOf(req.getReviewTimes()) : exist.getReviewSchedule())
                .userId(exist.getUserId())
                .bookId(exist.getBookId())
                .collectionId(exist.getCollectionId())
                .build();
        plansMapper.updateById(update);
        // 覆盖式更新计划关联的集合
        if (req.getCollectionIds() != null) {
            planItemMapper.delete(PlanItemDO::getPlanId, req.getId());
            for (Integer cid : req.getCollectionIds()) {
                planItemMapper.insert(PlanItemDO.builder().planId(req.getId()).collectionId(cid).build());
            }
        }
        return success(true);
    }
}


